import React, { useState, useMemo, useEffect } from 'react';
import { uDb, cline, Ret, useCmd, ListBox, WaitUmd, ListCheck, Title, PanelFind, useHigh, MainView,
    no_del, obj_str, BtTxt, d_sort, filter_row, GridTable, PanelTitle, Btn, is_empty, loc } from 'sui';
import { filter_item, get_box } from './cmd';

const reload = (fnDone, setMain, mod) => uDb(fnDone, `field/list/${mod}`, { line: cline() }, r => setMain(r), e => setMain([]));

const PBox = ({ cur, hreturn, mod="pbox" }) => {
    const [filter, setFilter] = useState();
    const [checked, setChecked] = useState([]);
    const [main, setMain] = useState([]);
    const [data, setData] = useState([]);
    const [high] = useHigh(140, 100);
    const umd = useCmd();

    useEffect(() => {
        reload(null, setMain, "box");
        reload(null, setData, get_box(mod));
    }, [mod]);

    const hadd = () => {
        umd.startWait();

        const val = [];
        const set = new Set();

        if (!is_empty(data)) {
            data.forEach(d => {
                if (set.has(d)) {
                    return;
                }

                val.push(d);
                set.add(d);
            });
        }

        if (!is_empty(checked)) {
            checked.forEach(d => {
                if (set.has(d)) {
                    return;
                }

                val.push(d);
                set.add(d);
            });
        }

        uDb(null, `field/md/${get_box(mod)}`,
            {
                line: cline(),
                v: val,
            },
            r => reload(umd.endWait, setData, get_box(mod)), e => umd.setErr());
    };

    const selectAll = () => {
        const user = filter_item(main, data, filter);
        if (is_empty(user)) {
            return;
        }

        const d = user.map(d => d);
        setChecked(d);
    };

    const getRow = useMemo(() => {
        if (is_empty(data)) {
            return null;
        }

        const ret = data.map(d => {
            return { sn: d };
        });

        d_sort(ret, "sn");

        return filter_row(ret, ["sn"], umd.filter);
    }, [data, umd.filter]);

    const filterRow = useMemo(() => {
        let user = filter_item(main, data, filter);
        if (is_empty(user)) {
            return null;
        }

        return user.map(d => <ListCheck key={d} value={d} checked={checked} setChecked={setChecked} uid={d}/>);
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [filter, main, data, checked]);

    const getUser = () => {
        const getCount = () => {
            if (is_empty(checked)) {
                return "";
            }

            return checked.length;
        };

        const Left = () => {
            return (
                <div className="inline-flex items-center justify-center">
                    <Btn hcmd={hadd}>{"<<"}</Btn>
                    <div className="ml-2">{getCount()}</div>
                </div>
            );
        };

        return (
            <div className="w-1/4 flex flex-col">
                <PanelFind cl="green" width="w-32" left={<Left/>} right={<Btn hcmd={selectAll}>{loc("l_270")}</Btn>} hcmd={v => setFilter(v)}/>
                <div className="overflow-y-auto" style={{ height: high - 50 + "px" }}>
                    <ListBox>
                        {filterRow}
                    </ListBox>
                </div>
            </div>
        );
    };

    const delAll = (v) => {
        if (no_del()) {
            return;
        }

        umd.startWait();

        uDb(null, `field/md/${get_box(mod)}`,
            {
                line: cline(),
                v: [],
            },
            r => reload(umd.endWait, setData, get_box(mod)), e => umd.setErr());
    };

    const hDel = (v) => {
        if (no_del()) {
            return;
        }

        umd.startWait();

        const sn = obj_str(v, "sn");
        const val = data.filter(d => d !== sn);

        uDb(null, `field/md/${get_box(mod)}`,
            {
                line: cline(),
                v: val,
            },
            r => reload(umd.endWait, setData, get_box(mod)), e => umd.setErr());
    };

    const Left = () => <Title mod={loc("l_736")} sub={loc("l_799")}/>;

    const col = [
        {name: loc("l_238"), key: 'e_opt', width: 100, formatter: props => {
            const d = props.row;
            return <BtTxt hcmd={() => hDel(d)}>{loc("l_237")}</BtTxt>;
        }},
        {name: loc("l_800"), key: 'sn', width: 200},
    ];

    return (
        <MainView>
            <PanelTitle left={<Left/>} right={<Ret color="green" hcmd={hreturn}/>} cl="gray"/>
            <div className="flex flex-row">
                <div className="w-3/4 border-r-2 border-blue-300">
                    <PanelFind hcmd={umd.setFilter} right={<Btn hcmd={delAll}>{loc("l_540")}</Btn>} cl="green"/>
                    <GridTable col={col} row={getRow} high={high}/>
                </div>
                {getUser()}
            </div>
            <WaitUmd umd={umd}/>
        </MainView>
    );
};

export {PBox};
